<template>
  <div class="container">
    <!-- 顶部操作栏 -->
    <el-card class="top-bar">
      <el-button type="primary" @click="connect">连接</el-button>
      <el-button type="danger" @click="disconnect">断开</el-button>
      <el-button type="success" @click="disconnect2">导入第二配置</el-button>
      <el-tag style="margin-left: 10px;" :closable="false"
        :color="state.status === '已连接' ? 'success' : state.status === '连接错误' ? 'danger' : 'info'">
        <el-icon v-if="state.status === '已连接'">
          <Check />
        </el-icon>
        <el-icon v-else-if="state.status === '连接错误'">
          <Close />
        </el-icon>
        <el-icon v-else>
          <Loading />
        </el-icon>
      </el-tag>
    </el-card>

    <el-card class="main">

      <!-- 主内容区域 -->
      <el-row class="main-content">
        <!-- 左侧列表 -->

        <el-col :span="3" class="sidebar">
          <div v-for="user in state.privateUsers" :key="user.id" class="list-item" @click="selectItem(user, 'private')">
            <span>{{ user.name }}</span>
            <el-badge v-if="user.unreadCount > 0" :value="user.unreadCount" />
          </div>
          <div v-for="group in state.groups" :key="group.id" class="list-item" @click="selectItem(group, 'group')">
            <span>{{ group.name }}</span>
            <el-badge v-if="group.unreadCount > 0" :value="group.unreadCount" />
          </div>
        </el-col>

        <!-- 右侧聊天区域 -->
        <el-col :span="21" class="chat-area">
          <div v-if="selectedType && selectedId">
            <el-card>
              <template #header>
                <div class="chat-header">
                  <h4>{{ selectedType === 'private' ? '私聊' : '群聊' }} - {{ selectedName }}</h4>
                </div>
              </template>
              <div>
                <div class="message-list">
                  <div v-for="(msg, index) in currentMessages" :key="msg.messageId" style="min-height: 50px;">
                    <div :class="[msg.senderId == state.userId ? 'message-self' : 'message-item']">
                      <!-- 文本消息 -->
                      <p v-if="msg.content != null || msg.content != ''">
                        {{ msg.content }}
                      </p>
                      <!-- 图片消息 -->
                      <div v-for="fileUrl in msg.files" :key="fileUrl">
                        <img v-if="fileUrl.fileType === 2" :src="fileUrl.fileUrl" class="message-image" />
                        <!-- 语音消息 -->
                        <audio v-if="fileUrl.fileType === 3" :src="fileUrl.fileUrl" controls
                          class="message-audio"></audio>

                        <!-- 视频消息 -->
                        <video v-if="fileUrl.fileType === 4" :src="fileUrl.fileUrl" controls
                          class="message-video"></video>

                        <!-- 文件消息 -->
                        <div v-if="fileUrl.fileType === 5" class="message-file">
                          <a :href="fileUrl.fileUrl" target="_blank">{{ fileUrl.fileName }}</a>
                        </div>
                      </div>


                    </div>
                    <div :class="[msg.senderId == state.userId ? 'avatar-self' : 'avatar-item']">
                      <img src="http://127.0.0.1:9090/pet/20250319/58befd9d433142c58a87622e6bf7ff76.png" class="avatar"
                        style="width: 30px;height: 30px;border-radius: 50%;" />
                      <!-- <div>{{ formatTime(msg.timestamp) }}</div>
                    <div>{{  msg.senderId }}:</div> -->
                    </div>
                  </div>
                </div>

              </div>
              <div class="message-box" style="border: 1px solid #e0e0e0; padding: 10px; border-radius: 8px;">
                <!-- 选择文件区域 -->
                <div style="display: flex; align-items: center; margin-bottom: 10px;">
                  <el-upload class="upload-demo" action="http://localhost:8081/upload"
                    :headers="{ Authorization: `Bearer ${state.jwtToken}` }" :on-success="handleFileSuccess"
                    :on-error="handleFileError" :file-list="currentUploadedFiles" multiple>
                    <el-button size="small" type="primary" style="margin-right: 10px;">选择文件</el-button>
                  </el-upload>
                </div>

                <!-- 输入消息内容区域 -->
                <div style="margin-bottom: 10px;">
                  <el-input v-model="currentMessageContent" type="textarea" placeholder="输入消息内容" :rows="2"
                    style="width: 100%; border: none; box-shadow: none; outline: none;"
                    :textarea-style="{ border: 'none', boxShadow: 'none', outline: 'none' }" />
                </div>

                <!-- 发送按钮 -->
                <div style="text-align: right;">
                  <el-button type="primary" @click="sendMessage">发送</el-button>
                </div>
              </div>
            </el-card>
          </div>
        </el-col>
      </el-row>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, computed } from 'vue';
import SockJS from 'sockjs-client';
import { Client } from '@stomp/stompjs';
import axios from 'axios';
import { ElMessage } from 'element-plus';
import { Check, Close, Loading } from '@element-plus/icons-vue';
interface WSMessage {
  type: string;
  senderId: string;
  content: any; // 支持文本或文件内容
  timestamp: number;
  messageType: number; // 消息类型（1=文本，2=图片，3=语音，4=视频，5=文件）
}

interface User {
  id: string;
  name: string;
  unreadCount: number;
}

interface Group {
  id: string;
  name: string;
  unreadCount: number;
}

const state = reactive({
  jwtToken: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxNzQyMjgwNDcxMDc3MDAxIiwiZXhwIjoxNzQyMzE2NzM3LCJpYXQiOjE3NDIyODA3Mzd9.6pwIq_PWC3dsItPtcJPKhgFyva_jfF6HDpX5g8vLO1c',
  userId: '1742280471077001',
  privateUsers: [
    { id: '1742269277363001', name: '用户A', unreadCount: 0 },
    { id: '1742280471077001', name: '用户B', unreadCount: 2 },
    { id: '1742269277363003', name: '用户C', unreadCount: 1 }
  ],
  groups: [
    { id: '1901941636981186561', name: '群组A', unreadCount: 0 },
    { id: '1901941636981186562', name: '群组B', unreadCount: 3 },
    { id: '1901941636981186563', name: '群组C', unreadCount: 1 }
  ],
  privateMessages: [] as WSMessage[],
  groupMessages: [] as WSMessage[],
  stompClient: null as Client | null,
  status: '未连接'
});

const selectedType = ref<string | null>(null); // 当前选中的类型（private/group）
const selectedId = ref<string | null>(null); // 当前选中的ID
const selectedName = ref<string | null>(null); // 当前选中的名称
const currentMessageContent = ref(''); // 当前输入的消息内容
interface FileItem {
  url: string;
  name: string;
  size: number;
  fileType: number;
}

const currentUploadedFiles = ref<FileItem[]>([]); // 当前上传的文件列表
const selectItem = (item: User | Group, type: 'private' | 'group') => {
  selectedType.value = type;
  selectedId.value = item.id;
  selectedName.value = item.name;

  // 清除未读消息数
  if (type === 'private') {
    const userIndex = state.privateUsers.findIndex(u => u.id === item.id);
    if (userIndex !== -1) {
      state.privateUsers[userIndex].unreadCount = 0;
    }
  } else {
    const groupIndex = state.groups.findIndex(g => g.id === item.id);
    if (groupIndex !== -1) {
      state.groups[groupIndex].unreadCount = 0;
    }
  }
};
const connect = async () => {
  if (!state.jwtToken || !state.userId) {
    ElMessage.error('请先输入有效的 JWT Token 和用户ID');
    return;
  }

  const socket = new SockJS(`http://localhost:8081/ws-sockjs?token=${state.jwtToken}`);
  state.stompClient = new Client({
    webSocketFactory: () => socket,
    onConnect: async () => {
      state.status = '已连接';
      ElMessage.success('连接成功');

      // // 请求私聊历史消息
      // try {
      //   const res = await axios.get('http://localhost:8081/chat/private/history', {
      //     params: { senderId: state.userId, receiverId: state.userId, limit: 20 },
      //     headers: { Authorization: `Bearer ${state.jwtToken}` }
      //   });
      //   if (res.data.state) {
      //     state.privateMessages = res.data.data;
      //   }
      // } catch (error) {
      //   ElMessage.error('获取私聊历史消息失败' + error);
      // }

      // // 请求群聊历史消息
      // try {
      //   const res = await axios.get('http://localhost:8081/chat/group/history', {
      //     params: { groupId: state.groups[0]?.id, limit: 20 },
      //     headers: { Authorization: `Bearer ${state.jwtToken}` }
      //   });
      //   if (res.data.state) {
      //     state.groupMessages = res.data.data;
      //   }
      // } catch (error) {
      //   ElMessage.error('获取群聊历史消息失败' + error);
      // }

      // 订阅消息
      state.privateUsers.forEach(user => {
        state.stompClient?.subscribe(`/user/${String(user.id)}/queue/messages`, (message) => {
          console.log('私聊消息', message);
          const msg = JSON.parse(message.body);
          msg.files = JSON.parse(msg.files);
            state.privateMessages.push(msg);
            console.log('privateMessages', state.privateMessages);
            const userIndex = state.privateUsers.findIndex(u => u.id === msg.senderId);
            if (userIndex !== -1) {
              state.privateUsers[userIndex].unreadCount++;
            }
        });
      });

      state.groups.forEach(group => {
        state.stompClient?.subscribe(`/topic/group.${group.id}`, (message) => {
          console.log('群聊消息', message);
          const msg = JSON.parse(message.body);
          if (msg.files) {
            msg.files = JSON.parse(msg.files);
          }
          state.groupMessages.push(msg);
          console.log('groupMessages', state.groupMessages);
          const groupIndex = state.groups.findIndex(g => g.id === msg.groupId);
          if (groupIndex !== -1) {
            state.groups[groupIndex].unreadCount++;
          }
        });
      });
    },
    onStompError: (error) => {
      ElMessage.error('STOMP协议错误' + error);
      state.status = '连接错误';
    }
  });

  state.stompClient.activate();
};

const disconnect = () => {
  state.stompClient?.deactivate();
  state.status = '已断开';
  ElMessage.info('已断开连接');
};

const disconnect2 = () => {
  state.userId = '1742269277363001';
  state.jwtToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxNzQxNzY3NDgzMjI2MDAxIiwiZXhwIjoxNzQxOTczNjc5LCJpYXQiOjE3NDE5Mzc2Nzl9.BAvb3Jqu5aKAP55Ds5lmcRHJ_yhpe3uIFC7AMLoACSg';
};

const sendMessage = () => {
  if (!state.stompClient?.active) {
    ElMessage.error('请先建立连接');
    return;
  }

  if (!selectedId.value) {
    ElMessage.error('请先选择聊天对象');
    return;
  }
  const attachments = currentUploadedFiles.value.length
    ? currentUploadedFiles.value.map(file => ({
      fileUrl: file.url,
      fileType: file.fileType,
      fileName: file.name,
      fileSize: file.size
    }))
    : [];
  console.log('发送文件', attachments);


  const messageType = currentUploadedFiles.value.length ? currentUploadedFiles.value[0].fileType : 1;

  const message = {
    senderId: state.userId,
    recipientId: selectedType.value === 'private' ? selectedId.value : '',
    groupId: selectedType.value === 'group' ? selectedId.value : '',
    content: currentMessageContent.value, // 文本内容
    files: JSON.stringify(attachments),
    messageType,
    timestamp: Date.now(),
    type: selectedType.value === 'private' ? 'PRIVATE_MESSAGE' : 'GROUP_MESSAGE'
  };
  console.log('发送消息', message);

  state.stompClient.publish({
    destination: selectedType.value === 'private' ? '/app/chat.private' : '/app/chat.group',
    body: JSON.stringify(message)
  });
  currentMessageContent.value = '';
  currentUploadedFiles.value = [];
};

const handleFileSuccess = (response: any, file: any) => {
  console.log(response);
  console.log(file);
  if (response.state) {
    currentUploadedFiles.value.push({
      url: response.data,
      name: file.name,
      size: file.size,
      fileType: getFileType(file.name)
    });
  } else {
    ElMessage.error('文件上传失败');
  }
};

const handleFileError = () => {
  ElMessage.error('文件上传失败');
};

const getFileType = (fileName: string): number => {
  console.log(fileName);
  const suffix = fileName.split('.').pop()?.toLowerCase();
  const imageTypes = ['jpg', 'jpeg', 'png', 'gif'];
  const audioTypes = ['mp3', 'wav'];
  const videoTypes = ['mp4', 'avi', 'mov'];

  if (imageTypes.includes(suffix || '')) return 2;
  if (audioTypes.includes(suffix || '')) return 3;
  if (videoTypes.includes(suffix || '')) return 4;
  return 5;
};

const formatTime = (timestamp: number) => {
  return new Date(timestamp).toLocaleTimeString();
};

const currentMessages = computed(() => {
  return selectedType.value === 'private' ? state.privateMessages : state.groupMessages;
});
</script>

<style scoped lang="scss">
.container {
  max-width: 100%;
  margin: 20px auto;
  padding: 20px;
}

.top-bar {
  margin-bottom: 20px;
}

.sidebar {
  height: calc(100vh - 100px);
  overflow-y: auto;

  div {
    cursor: pointer;
    padding: 10px;

    &:hover {
      background-color: #f5f5f5;
    }

    span {
      display: inline-block;
      margin-right: 10px;
    }

    &.active {
      background-color: #f5f5f5;
    }

  }
}

.chat-area {
  height: 80vh;
  overflow-y: auto;
}

.message-list {
  height: 30vh;
  overflow-y: auto;
  margin-bottom: 20px;
  position: relative;
}

.message-item {
  position: absolute;
  left: 10px;
  margin-top: 5px;
  padding: 10px;
  border-radius: 8px;
  margin-left: 30px;
  background-color: #f5f5f5;
  max-width: 70%;
}

.avatar-item {
  position: absolute;
  left: 0;
}

.avatar-self {
  position: absolute;
  right: 0;
}

.message-self {
  margin-top: 5px;
  padding: 10px;
  border-radius: 8px;
  margin-left: 30px;
  background-color: #f5f5f5;
  max-width: 70%;
  position: absolute;
  right: 40px;
  background-color: #d1e7ff;
}

.message-image {
  width: 200px;
  height: auto;
  margin-top: 10px;
}

.message-audio,
.message-video {
  display: block;
  margin-top: 10px;
}

.message-file a {
  color: #409eff;
  text-decoration: underline;
  font-size: 14px;
}
</style>